\\ *** File-Interface *** 25may86we Dieses File enthält das File-Interface. Damit wird der Zugriff auf normale GEM-Dos Files möglich. Wenn ein File mit USE benutzt wird, beziehen sich alle Worte, die mit dem Massenspeicher arbeiten, auf dieses File. Ebenfalls un- terstützt das File-Interface Subdirectories, sogar mit mehr Möglichkeiten als unter GEM-Dos. Da es normalerweise im Direktzugriff geladen wird, müssen die View-Felder der Worte anschließend gepatched werden (s. STARTUP.SCR) \ File interface load and patch block 13oct86we Onlyforth 1 3 +thru \ savesystem, always needed 4 $21 +thru \ Fileinterface ' (makeview Is makeview ' remove-files Is custom-remove ' filer/w Is r/w \ File functions for savesystem 05oct86we : arguments ( n -- ) depth 1- > abort" not enough Parameters" ; | Code (createfile ( C$ -- handle ) 0 # A7 -) move \ normal file, no protection SP )+ D6 move D6 reg) A0 lea .l A0 A7 -) move .w $3C # A7 -) move 1 trap 8 A7 addq D0 SP -) move Next end-code | Code (closefile ( handle -- f ) SP )+ A7 -) move $3E # A7 -) move 1 trap 4 A7 addq D0 SP -) move Next end-code \ write into file 05oct86we | Code (filewrite ( buff len handle -- n ) SP )+ D0 move .l D2 clr .w SP )+ D2 move SP )+ D6 move D6 reg) A0 lea .l A0 A7 -) move \ buffer adress D2 A7 -) move \ buffer length .w D0 A7 -) move \ handle $40 # A7 -) move \ call WRITE 1 trap $0C # A7 adda D0 SP -) move \ Fehlerflag, geschriebene Bytes Next end-code \ savesystem 13oct86we : savesystem save flush \ Filename follows bl word count dup 0= abort" missing filename" over + off (createfile dup >r 0< abort" no device " $601A 0 ! align here $1C - $04 ! 0 , 0 , 0 here r@ (filewrite here - abort" write error" r> (closefile 0< abort" close error" ; \ disk errors 13oct86we Vocabulary Dos Dos also definitions | ' 2- Alias body> \ just for style | : 2digits ( n -- adr len ) base push decimal extend <# # # #> ; | 0 Constant #adr \ will hold the adr of "00" in following abort" ..." \ disk errors bp 11oct86 : .diskerror ( -n -- ) negate &13 case? abort" Disk schreibgeschützt" &33 case? abort" Datei nicht gefunden" &34 case? abort" Pfad nicht gefunden" &36 case? abort" Zugriff nicht möglich" &37 case? abort" Ungültige Handle#" &46 case? abort" ungültiges Laufwerk" 2digits #adr swap cmove true [ here 2+ ( adress of counted string ) ] abort" Dos-Error #00" [ count + 2- ' #adr >body ! ( adr of "00") ] ; : ?diskabort ( -n -- ) dup 0< IF .diskerror THEN drop ; \ File control block structure 09sep86we | : Fcbyte ( n len -- n' ) \ defining word for fcb contents Create over c, + does> c@ + ; &25 Constant filenamelen \ only SHORT pathes will fit ! | 0 2 Fcbyte nextfile \ link to next file filenamelen Fcbyte filename \ name of file 4 Fcbyte filesize \ size in Bytes , low..high 2 Fcbyte filehandle \ handle from GEMdos 2 Fcbyte fileno \ fileno. for VIEW Constant b/fcb \ bytes per file : handle ( -- n ) isfile@ filehandle @ ; \ *** nextfile must be the first field ! \ position into block 13oct86we Code lseek ( d handle n -- d' ) SP )+ A7 -) move SP )+ A7 -) move .l SP )+ A7 -) move .w $42 # A7 -) move 1 trap $0A # A7 adda .l D0 SP -) move Next end-code : position ( d handle -- f ) 0 lseek 0< ?exit drop false ; : position? ( handle -- d ) 0 0 rot 1 lseek dup 0< IF ?diskabort THEN ; \ read and write a memory area 05oct86we Code (fileread ( buff len handle -- n ) SP )+ D0 move .l D2 clr .w SP )+ D2 move SP )+ D6 move D6 reg) A0 lea .l A0 A7 -) move \ buffer adress D2 A7 -) move \ buffer length .w D0 A7 -) move \ handle $3F # A7 -) move \ call READ 1 trap $0C # A7 adda D0 SP -) move \ Fehlerflag bzw. gelesene Bytes Next end-code ' (filewrite Alias (filewrite \ (open-file setdta 26oct86we Code (openfile ( C$ -- handle ) 2 # A7 -) move SP )+ D6 move D6 reg) A0 lea .l A0 A7 -) move .w $3D # A7 -) move 1 trap 8 A7 addq D0 SP -) move Next end-code Create dta &44 allot Code setdta ( addr -- ) SP )+ D6 move D6 reg) A0 lea .l A0 A7 -) move .w $1A # A7 -) move 1 trap 6 A7 addq Next end-code ' (closefile Alias (closefile ' (createfile Alias (createfile \ search for files 03oct86we Code search0 ( C$ attr -- f ) \ search for first file SP )+ A7 -) move SP )+ D6 move D6 reg) A0 lea .l A0 A7 -) move .w $4E # A7 -) move 1 trap 8 A7 addq D0 SP -) move Next end-code Code searchnext ( -- f ) \ search for next file $4F # A7 -) move 1 trap 2 A7 addq D0 SP -) move Next end-code \ Create a subdir bp 11 oct 86 Code (makedir ( C$ -- f ) \ Create a subdir $39 # D1 move Label long-adr SP )+ D6 move D6 reg) A0 lea .l A0 A7 -) move .w D1 A7 -) move 1 trap 6 A7 addq D0 SP -) move Next end-code Code (setdir ( C$ -- f ) $3B # D1 move long-adr bra end-code \ select drive 09sep86we Code setdrive ( n -- ) SP )+ A7 -) move $0E # A7 -) move 1 trap 4 A7 addq Next end-code Code getdrive ( -- n ) $19 # A7 -) move 1 trap 2 A7 addq D0 SP -) move Next end-code Code getdir ( addr n -- f ) \ n is drive, string in addr SP )+ A7 -) move SP )+ D6 move D6 reg) A0 lea .l A0 A7 -) move .w $47 # A7 -) move 1 trap 8 A7 addq D0 SP -) move Next end-code \ file sizes b30aug86we : (capacity ( fcb -- n) \ calculates size in blocks filesize 2@ 2dup or 0= IF drop exit THEN b/blk um/mod swap IF 1+ THEN ; \ add 1 block for rest | : in-range ( block fcb -- f) \ makes sure, block is in file (capacity u< not &36 * ; \ Errorcode -&36 \ read and write into files bp 11 oct 86 | : set-pos ( block handle -- f) >r b/blk um* r> position ; | : fileaccess ( buff block fcb -- buff len handle/ errorcode) 2dup in-range ?dup IF >r 2drop drop r> rdrop exit THEN filehandle @ under set-pos ?dup IF >r 2drop r> rdrop exit THEN b/blk swap ; | : fileread ( buff block fcb -- ff / errorcode ) fileaccess (fileread dup 0> IF drop false THEN ; | : filewrite ( buff block fcb -- ff / errorcode ) fileaccess (filewrite dup 0> IF drop false THEN ; \ twiggling the file variables bp 11 oct 86 : scan-name ( C$ -- adr len') \ length of "C"-string $1000 over swap 0 scan drop over - ; : .file ( fcb --) \ print only filename ?dup 0= IF ." DIRECT ! " exit THEN body> >name .name ; : .fcb ( fcb -- ) \ print filename dup filehandle @ 2 .r dup filesize 2@ 6 d.r 3 spaces dup .file 2 spaces filename scan-name type ; : !files ( fcb -- ) \ set file and isfile dup isfile ! fromfile ! ; \ PATHes bp 11 oct 86 | &30 Constant pathlen \ max. len of all pathes Variable pathes pathlen allot \ counted string of pathes pathes off : pathes? ( -- ) \ print a list of the pathes cr 3 spaces pathes count type ; : setpath ( adr len --) \ set's the list of pathes pathlen min pathes place Ascii ; pathes count + c! pathes c@ 1+ pathes c! ; \\ PATH : see elsewhere in this file \ search for files bp 11 oct 86 Variable workspace &64 allot \ place for c$ | : try.path ( adr len fcb attr -- f ) 2swap workspace swap 2dup + >r move swap filename r> filenamelen cmove workspace swap search0 0= ; | : makec$ ( adr len -- c$ ) \ make adr len to a c$ workspace swap 2dup + >r move r> off ( make a c$ ) workspace ; \ " bp 11 oct 86 | Variable sfile \ "dirty" variable | 7 Constant defaultattr \ find all filetypes | : path@ ( adr len -- adr len1 adr len2) \ isolate a path Ascii ; skip 2dup 2dup Ascii ; scan nip - ; : (searchfile ( fcb -- ff/ C$ f) \ search for file in path sfile ! pathes count \ and in act. directory BEGIN path@ sfile @ defaultattr try.path IF 2drop workspace true exit THEN Ascii ; scan dup 0= UNTIL nip ; : searchfile ( fcb -- C$ ) \ file was found in path (searchfile ?exit -&33 ?diskabort ; \ open a file, filer/w b26oct86we | : @length ( -- d) dta &26 + 2@ ; | : copylength ( fcb --) @length rot filesize 2! ; : (open ( fcb --) \ open file dup filehandle @ IF drop exit THEN dta setdta dup searchfile over copylength (openfile dup ?diskabort swap filehandle ! ; Forth definitions : capacity ( -- n) isfile@ ?dup IF dup (open (capacity exit THEN blk/drv ; Dos definitions \ filer/w, Create a file bp 11 oct 86 : filer/w ( buff block fcb f -- f) over 0= IF STr/w exit THEN over (open IF fileread ELSE filewrite THEN dup ?diskabort ; : createfile ( fcb --) \ create a file in fcb dup filename (createfile dup ?diskabort over filehandle ! 0 0 rot filesize 2! offset off ; \ store names for files bp 11 oct 86 | : !name ( adr len --) \ store name in record 2dup erase >r name count dup r> < not abort" string too long" >r swap r> cmove ; : !fcb ( fcb --) \ next word is filename dup filehandle off filename filenamelen !name ; \ print dta and directory 26oct86we | : .dtaname ( addr --) \ addr is addr of name dup BEGIN dup c@ ?dup WHILE emit 1+ REPEAT - &15 + spaces ; : .dta ( --) \ print contents of dta cr dta &21 + c@ $10 and IF Ascii D ELSE bl THEN emit space dta &30 + .dtaname @length &10 d.r ; : (dir ( attr adr len --) \ given a match string makec$ swap dta setdta search0 BEGIN 0= WHILE stop? 0= WHILE .dta searchnext REPEAT ; \ primitives for fcb's bp 18May86 User file-link file-link off \ list thru files | : #file ( -- n) \ View number of next file file-link @ dup IF fileno @ THEN 1+ ; : forthfiles ( --) \ print a list of : file-link @ \ forthword,filename,handle,len BEGIN dup WHILE cr dup .fcb @ stop? UNTIL drop ; \ Close a file bp 18May86 | ' save-buffers >body $C + @ Alias backup | : filebuffer? ( fcb -- fcb bufaddr/flag) prev BEGIN @ dup WHILE 2dup 2+ @ = UNTIL ; | : flushfile ( fcb -- ) \ flush file buffers BEGIN filebuffer? ?dup WHILE dup backup emptybuf REPEAT drop ; : (close ( fcb --) \ close file in fcb dup flushfile filehandle dup @ ?dup 0= IF drop exit THEN swap off (closefile -$41 case? ?exit ?diskabort ; \ Create fcb's bp 11 oct 86 Forth definitions : File ( -- ) \ Create a fcb Create here b/fcb allot dup b/fcb erase #file over fileno ! file-link @ over file-link ! swap ! does> !files ; : direct 0 !files ; \ switch to direct access \ flush buffers & misc. bp 8jun86 : flush ( --) flush file-link BEGIN @ ?dup WHILE dup (close REPEAT ; : file? isfile@ .file ; \ print current file : list ( n --) 3 spaces file? list ; : path ( -- ) \ this is a smart word ! name count dup 0= IF 2drop pathes? exit THEN dup 1 = IF over c@ Ascii ; = IF 2drop pathes off exit THEN THEN setpath ; \ File Interface User words 26oct86we | : isfile? ( adr -- adr f) \ is adr a fcb ? file-link BEGIN @ dup 0= ?exit 2dup 2- = UNTIL drop true ; | : ?isfile@ isfile@ body> isfile? 0= abort" not in direct mode" >body ; : open ?isfile@ (open offset off ; : close ?isfile@ (close ; : assign close isfile@ !fcb open ; : make ?isfile@ dup !fcb createfile ; : use >in @ name find \ create a fcb if not present ! IF isfile? IF execute drop exit THEN THEN drop dup >in ! File dup >in ! ' execute >in ! assign ; \ File Interface User words bp 11 oct 86 : makefile >in @ file dup >in ! ' execute >in ! make ; : from isfile push use ; \ sets only fromfile : loadfrom ( n --) \ load 1 scr from file isfile push fromfile push use load close ; : include 1 loadfrom ; : eof ( -- f) \ end of file ? isfile@ dup filehandle @ position? rot filesize 2@ d= ; : files $10 " *.*" count (dir ; : files" $10 Ascii " word count (dir ; \ extend files bp 11 oct 86 | : >fileend isfile@ filesize 2@ handle position ?diskabort ; | : addsize isfile@ filesize dup 2@ b/blk 0 d+ rot 2! ; | : addblock ( n --) \ add block n to file buffer b/blk 2dup bl fill >fileend handle (filewrite dup ?diskabort b/blk - IF close abort" Disk voll" THEN addsize ; : (more ( n --) capacity swap bounds ?DO I addblock LOOP ; : more ( n --) ?isfile@ (open (more close ; \ make,kill and set directories bp 11 oct 86 | : dir$ ( -- adr ) name count makec$ ; : makedir dir$ (makedir ?diskabort ; : dir name count 0 case? IF getdrive 2dup 1+ getdir ?diskabort cr 3 spaces Ascii A + emit ." :" scan-name type exit THEN makec$ (setdir ?diskabort ; | : driveset Create c, Does> c@ setdrive ; 0 driveset A: 1 driveset B: 2 driveset C: 3 driveset D: \ words for VIEWing bp 11 oct 86 | $200 Constant viewoffset \ max. &512 kbyte lange Files | : (makeview ( -- n) \ calc. view field for a name blk @ dup 0= ?exit loadfile @ ?dup IF fileno @ viewoffset * + THEN ; : (view ( blk -- blk') \ select file and leave block dup 0= ?exit viewoffset u/mod file-link BEGIN @ dup WHILE 2dup fileno @ = UNTIL dup searchfile drop \ file not found : abort !files drop ; \ ugly FORGETing of files bp 11 oct 86 : remove? ( dic symb addr -- dic symb addr f) dup heap? IF 2dup u> exit THEN 2 pick over 1+ u< ; | : remove-files ( dic symb -- dic symb) \ flush files ! isfile @ remove? nip IF 0 !files THEN fromfile @ remove? nip IF fromfile off THEN file-link BEGIN @ ?dup WHILE remove? IF dup (close THEN REPEAT file-link remove ; \ convey for files bp 11 oct 86 | : togglefiles ( -- ) \ changes isfile and fromfile isfile@ fromfile @ isfile ! fromfile ! ; : convey ( [blk1 blk2] [to.blk --) 3 arguments >r 2dup swap - >r togglefiles dup capacity 1- > togglefiles r> r@ + capacity 1- > or abort" wrong range!" r> convey ; \ print a list of all blocks bp 9Apr86 : .blocks prev BEGIN @ ?dup WHILE stop? abort" stopped" cr dup u. dup 2+ @ dup 1+ IF ." Block :" over 4+ @ 5 .r ." File : " [ Dos ] .file dup 6 + @ 0< IF ." updated" THEN ELSE ." Block empty" drop THEN REPEAT ; \ create a file of direct blocks bp 26oct86we Dos also | File outfile : blocks>file ( from to -- ) \ Name des Files folgt ?isfile@ -rot outfile make 1+ swap ?DO I over (block b/blk handle (filewrite b/blk - abort" write error" LOOP close isfile ! ; bp 4oct86 MAKEVIEW erzeugt aus ISFILE und BLK das Viewfeld CUSTOM-REMOVE erlaubt das FORGETten von eig. Datenstrukturen R/W setzt Forthblöcke in Disksektoren um .... 13oct86we 13oct86we ARGUMENTS liefert etwas Sicherheit ... (CREATEFILE erzeugt ein File, dessen Namen in C$ steht, im aktuellen oder im durch den Pfadnamen angegebenen Directory. HANDLE ist die Handle des Files oder ein Fehlerflag. Es wird immer ein "ganz normales" File erzeugt. (CLOSEFILE Schließt das File mit der Handle HANDLE. Dabei sollten alle TOS-Buffer zurückgeschrieben und das Directory gesichert werden. F ist ein Fehlerflag. Die Handle ist anschließend ungültig. 13oct86we (FILEWRITE schreibtLEN Bytes in das File HANDLE. Die Bytes werden ab Adresse BUFF im Speicher geholt. N ist die Zahl der geschriebenen Bytes oder eine Fehlernummer, wenn N zwischen -66 und -1 liegt. 13oct86we SAVESYSTEM speichert ein FORTH-System im aktuellen Zustand auf Diskette ab. Voodoo-Code für den GEMDOS-Fileheader; keine Relokatinsinfos Mit SAVESYSTEM lassen sich eigene Arbeitssysteme oder auch Applikationen erstellen, denen man ihre FORTH-Herkunft nicht mehr ansieht. Stellen Sie ein System nach Ihren Wünschen zusammen, und spei- chern Sie es dann mit SAVESYSTEM MYPROG.PRG ab. 13oct86we DOS enthält die "unwichtigen" Worte des Fileinterfaces BODY> ( cfa -- pfa ) Kompilationsadresse in Parameterfeldadresse umwandeln ... Diese Worte werden für die üble Patcherei in .diskabort benutzt. Nur so kann die Dos-Fehlernummer in der abort" -Meldung unter- gebracht werden. Bei einer Ausgabe mit . wäre keine Umleitung über ERRORHANDLER möglich. 13oct86we -n ist die Fehlernummer; es wird der zugehörige Text ausgedruckt Ist die Fehlernummer nicht in den CASE-Anweisungen zu finden, wird Dos-Error # ausgegeben. Die Fehlernummer wird dann in den abort" String gepatched. Dieses Verfahren ist zwar äußerst häßlich, nichtsdestoweniger aber sehr effektiv. Prüft, ob ein Fehler vorliegt und druckt ggf. den Text aus und ABORTed anschließend. bp 4oct86 Definierendes Wort für die Benamsung der Felder eines File control blocks ( FCB bzw. FILE in den Stackkommentaren) Zeiger auf den nächsten FCB Platz für max. 24 Zeichen für den TOS-Filenamen Länge des Files in Bytes Handlenummer, die das TOS beim Öffnen eines Files liefert. Eine eigene Nummer, die in das VIEW-Feld eingetragen wird. Länge eines FCB wird auch berechnet... Liefert die Handle des aktuellen Files. Null, falls das File nicht offen . bp 4oct86 LSEEK N ist ein Flag, das angibt, ob relativ zum Fileanfang, zum Fileende oder zur aktuellen Position im File positioniert werden soll. HANDLE ist die Handle des Files, in dem positioniert wird und D die neue Position im File. D' ist die neue Position. POSITION positioniert auf das Byte d, gezählt vom Anfang des Files mit der Handle HANDLE . POSITION? liefert die Position des zuletzt gelesenen, geschriebenen oder mit POSITION bzw. LSEEK angewählten Bytes. 13oct86we FILEREAD liest LEN Bytes aus dem File HANDLE. Die Bytes werden ab Adresse BUFF im Speicher abgelegt. N ist die Zahl der gelesenen Bytes oder eine Fehlernummer, wenn N zwischen -66 und -1 liegt. Das headerlose (FILEWRITE bekommt nun einen Header im Vocabulary Dos. 26oct86we OPENFILE Öffnet ein File. Der Name steht im String C$. C$ ist durch ein $00-Byte begrenzt. HANDLE ist die diesem File zugeordnete Handle oder eine Fehlernummer. DTA ist ein 44 Byte großer Buffer, in dem einige Fileinformationen vom GEMDOS gehalten werden. SETDTA ADDR ist die Adresse der 'disk transfer area'. (CLOSEFILE und (CREATEFILE erhalten Header im Vocabulary Dos. 13oct86we SEARCH0 SEARCH0 sucht ein File. C$ ist der Name des File mit Pfad usw. . C$ wird, wie immer, durch ein $00-Byte begrenzt. ATTR ist ein Attributwort, das z.B. bestimmt, ob auch Subdirectories gefunden werden. F ist ein Fehlerflag. Die DTA enthält anschließend Filenamen, -länge usw. SEARCHNEXT sucht das nächste File mit dem bei SEARCH0 angegeben Namen... 13oct86we (MAKEDIR erzeugt ähnlich (CREATEFILE ein Subdirectory. C$ ist der Name des Directories, F ist ein Fehlerflag. (SETDIR setzt das durch C$ angegeben Subdirectory als das "Aktuelle", auf das sich alle Such- und "Erzeugungs-" operationen ohne eigenen Pfadnamen beziehen. bp 4oct86 SETDRIVE N ist die Nummer des aktuellen Laufwerkes, auf das sich alle Operationen ohne eigenen Pfadnamen beziehen. Vergleiche (SETDIR. Laufwerk A: hat die Nummer 0 ! GETDRIVE N ist die Nummer des bei SETDRIVE genannten Laufwerks. GETDIR Das durch (SETDIR gesetzte Subdirectory wird ab Adresse ADDR als C$ im Speicher abgelegt. N ist die Nummer des Laufwerkes ( Laufwerk A: hat die Nummer 1 !!!! ), denn verschiedene Laufwerke können verschiedene aktuelle Sub- directories haben. bp 4oct86 (CAPACITY FCB ist die Adresse des FCB des Files, von dem die Länge in Blocks bestimmt werden soll. N ist dann die Zahl der Blöcke in diesem File. IN-RANGE prüft, ob sich ein Block mit der Nummer BLOCK im File FCB befindet. Ist das nicht der Fall, wird als Fehlernummer -36 geliefert. Siehe auch ?DISKABORT 13oct86we SET-POS positioniert im File mit der Handle HANDLE auf den Anfangs des Blocks BLOCK. F ist ein Fehlerflag. FILEACCESS wird in FILEREAD und FILEWRITE benötigt. FILEREAD liest den Block BLOCK an die Adresse BUFF aus dem File FCB. Hinterläßt eine Fehlernummer. FILEWRITE überschreibt den Block BLOCK mit den Daten ab Adresse BUFF im File FCB. Hinterläßt eine Fehlernummer. bp 4oct86 SCAN-NAME 'LEN ist die Länge eines durch ein $00-Byte begrenzten C$. .FILE druckt den Forthnamen des Files mit der Adresse FCB. .FCB druckt Forthnamen, TOS-Namen, Handle und Länge des Files mit der Adresse FCB aus. !FILES setzt die Variable ISFILE und FROMFILE (darin steht das File, aus dem bei COPY und CONVEY gelesen wird) auf das File mit der Adresse FCB. bp 4oct86 PATHES Hier ist Platz für den durch SETPATH angegeben String, der die Namen der zu durchsuchenden Laufwerke und Directories enthält. PATHES? Druckt den Inhalt von PATHES aus. SETPATH Setzt PATHES auf den String ab der Adresse ADR, dessen Länge LEN ist. Anschließend wird noch ein ; angefügt, um auch den letzten Path korrekt zu beenden. bp 4oct86 WORKSPACE Hier wird aus File- und Pathnamen ein C$ zusammengebastelt. TRY.PATH ADR und LEN enthalten den Pfadnamen (aus PATHES mit PATH@ extrahiert), FCB ist die Adresse des Files und ATTR ein Attribut (siehe SEARCH0). Aus Pfadnamen und FCB wird in WORKSPACE ein String zusammengebastelt, der dann mit SEARCH0 gesucht wird. F gibt an, ob wir erfolgreich waren. MAKEC$ konvertiert einen durch ADR und LEN definierten String in einen C$ (durch ein $00-Byte begrenzt) und hinterläßt dessen Adresse. bp 4oct86 SFILE enthält die Adresse des FCB des gesuchten Files.DEFAULTATTR enstpricht "Suche alle Files, egal welches ATTR" PATH@ extrahiere aus dem noch nicht zum Suchen verwen- deten Teil von PATHES, der durch ADR und LEN angegeben wird, den nächsten zu durchsuchenden Pfad ADR LEN1. (SEARCHFILE durchsucht alle in PATHES stehenden Pfade nach dem in FCB stehenden Filenamen. Aufgehört wird, wenn das File gefunden wurde oder alle Pfade durchsucht wurden. Am Schluß wird auch der leere Pfad (Länge Null) durchsucht, der dem aktuellen Directory (siehe SETDIR) entspricht. SEARCHFILE Sucht das File FCB in allen Pfaden und im akt. Directory. Hinterlassen wird der vollständige Pfad des Files. bp 4oct86 @LENGTH holt die Länge des zuletzt gefundenen Files COPYLENGTH kopiert die Länge des zuletzt gefundenen Files in den Fcb FCB. (OPEN öffnet das durch FCB angegebene File und speichert LEN dort die Handle und Länge. Dazu muß es natürlich erst gesucht werden, denn nur dann steht die Länge in der DTA. CAPACITY N ist die Zahl der Blöcke im aktuellen (durch ISFILE angegeben) File. Ist ISFILE Null, so wird die Kapazität der Diskette im Direktzugriff angegeben. bp 4oct86 FILER/W ist das zentrale Wort für den Zugriff auf Files. BUFF ist die Adresse des Blocks BLOCK im Speicher, FCB die Nummer des Files (0 heißt Direktzugriff) und R/W gibt an, in welcher Richtung die Daten zu transportieren sind. F ist true, falls ein Fehler auftrat. CREATEFILE erzeugt ein File, dessen Name im Fcb FCB steht. Handle und Filelänge werden korrigiert. bp 4oct86 !NAME speichert einen auf !NAME folgenden String ab Adresse ADR mit maximaler Länge LEN im Speicher ab. Der String wird durch $00-Bytes begrenzt. !FCB speichert einen auf !FCB folgenden String im Fcb FCB ab. Die Handle wird gelöscht, weil das so zugewiesene File noch nicht geöffnet worden ist. 13oct86we .DTANAME druckt den Filenamen, er ab Adresse d in der DTA steht, linksbündig in einem Feld der Breite 15 aus. .DTA druckt den Inhalt der DTA formattiert aus. Zunächst wird ein "D" ausgegeben, das anzeigt, ob es sich um ein Subdirectory handelt, anschließend der Name gefolgt von der Länge des Files. (DIR druckt alle Files aus, auf die der String ADR LEN und das Attribut ATTR "passt". Die Ausgabe kann wie üblich angehalten und abgebrochen werden. bp 4oct86 FILE-LINK enthält einen Zeiger auf den FCB des zuletzt definierten Files. #FILE N ist die Nummer, die in das Viewfeld des nächsten zu definierenden Files eingetragen werden soll. FORTHFILES druckt die Forth- und TOS-Namen mit Handle und Länge aller definierten Files aus. Dazu wird FILE-LINK benutzt. Die Ausgabe kann wie üblich angehalten oder beendet werden. bp 4oct86 FILEBUFFER? guckt nach, ob zu dem File FCB noch ein Block- puffer exisitiert. Liefert false, falls keiner vorhanden ist. FLUSHFILE sichert alle zum File FCB gehörenden Blockpuffer auf dem Massenspeicher und löscht sie anschließend. (CLOSE sichert alle Blockpuffer, schließt anschließend das File, falls es nicht schon geschlossen war und ignoriert den Fehler mit der Nummer -65, weil der so oft auftritt... bp 4oct86 FILE ist ein definierendes Wort, daß einen FCB erzeugt. Wird der FCB später ausgeführt, so trägt er sich als aktuelles File und als FROMFILE ein. DIRECT ein "spezieller FCB" für den Direktzugriff. Der Direktzugriff ist immer dann interessant, wenn man einen Diskmonitor braucht, ihn aber gerade verliehen hat... bp 4oct86 FLUSH schließt zusätzlich alle Files.. FILE? druckt den Namen des aktuellen Files aus. LIST druckt zusätzlich den Filenamen aus... PATH druckt PATHES aus oder löscht PATHES oder setzt PATHES auf einen anderen String. 13oct86we ISFILE? F ist wahr, falls ADR die Kompilationsadresse eines FCB ist (also durch FILE erzeugt wurde...). ?ISFILE@ steht in ISFILE überhaupt ein File ? OPEN öffnet das aktuelle File. CLOSE schließt es. ASSIGN Anderer Filename in aktuellen FCB eintragen. MAKE Neu erzeugter Filename in aktuellen FCB.. USE Erzeuge FCB (mit Filenamen !), falls Name nicht schon vorhanden. Wenn Name vorhanden, prüfe ob es File ist. Trage dann FCB in ISFILE ein. 13oct86we MAKEFILE erzeugt FCB und File gleichen Namens. FROM setzt FROMFILE für COPY und CONVEY LOADFROM lädt den Screen N vom File, dessen Name auf LOADFROM folgt. z.B. 1 loadfrom forth_83.scr INCLUDE lädt den Loadscreen des Files... EOF F ist wahr, falls wir am Ende des Files angekommen sind. FILES liefert Inhaltsverzeichnis des akt. Directories.FILES" erlaubt Pfad- und Filenamen bp 4oct86 >FILEEND springe ans Ende des aktuellen Files ADDSIZE erhöht die Längenangabe im aktuellen FCB um 1024 Bytes. ADDBLOCK fügt den Block N am Fileende an. Außerdem wird ein leerer Buffer mit dieser Nummer angelegt. (MORE fügt n Blöcke am Fileende an. MORE Wie (MORE, jedoch etwas Sicherheit.. 13oct86we DIR$ ADR ist die Adresse eines auf DIR$ folgenden C$. MAKEDIR erzeugt ein Directory mit dem folgenden Namen.. DIR gibt, falls kein Name folgt, das aktuelle Lauf- werk und Subdirectory aus. Folgt ein Name, so wird er als das neue aktuelle Directory an das TOS übergeben. A: B: C: D: Kurzformen für SETDRIVE. 13oct86we VIEWOFFSET teilt das 16-Bit Viewfeld in ein Feld mit der Filenummer und ein Feld mit der Blocknummer. Die unteren 9 Bits sind für die Blocknummer reserviert. (MAKEVIEW macht aus BLK und der Nummer des geladenen Files LOADFILE eine 16-Bit Zahl, die von CREATE dann als Viewfeld hinterlegt wird. (VIEW zerlegt den Inhalt BLK eines Viewfeldes in Filenummer und Blocknummer BLK' . Der zur Filenummer gehörende FCB wird gesucht, und falls gefunden, in ISFILE und FROMFILE eingetragen. Kann kein FCB gefunden werden, so wird eine Fehlermeldung ausgegeben. bp 4oct86 REMOVE? DIC (SYMB) ist die Adresse im Dictionary (HEAP), oberhalb (unterhalb, der Heap wächst von oben nach unten !) derer alle Worte vergessen werden müssen. F gibt an, ob ADDR innerhalb des zu vergessenden Intervalls liegt. REMOVE-FILES guckt nach, ob ISFILE oder FROMFILE vergessen werden. Ist das der Fall, so werden sie auf den Direktzugriff umgeschaltet. Anschließend werden alle zu vergessenden Files geschlossen und aus der Liste aller Files FILE-LINK entfernt. bp 4oct86 TOGGLEFILES vertauscht ISFILE und FROMFILE. CONVEY prüft, ob die zu bewegenden Blöcke vorhanden sind und bewegt sie ggf. 13oct86we .BLOCKS listet den Inhalt der Blockpuffer auf. Angegeben werden Adresse, Blocknummer und Filename sowie, ob der Block geUPDATEd wurde. Bei der Entwicklung des Fileinterfaces war das ein nützliches Hilfsmittel. Dieser und der nächste Screen werden normalerweise vom Load- screen nicht mitkompiliert. 13oct86we Mit BLOCKS>FILE läßt sich eine Folge von Diskettenblöcken in einem File ablegen. Damit können Disketten, die bisher im Direktzugriff benutzt worden sind, auf das Fileinterface um- gestellt werden.